package bert.viewer;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.Timer;

import bert.Side;
import bert.TrackModel;
import bert.TrackSegment;
import bert.Vec2;

public class ViewerComponent extends JPanel {

	private static final long serialVersionUID = 6565204076642440239L;
	
	private TrackModel trackModel;
	private Timer timer;
	
	public ViewerComponent() {
		setBorder(BorderFactory.createLineBorder(Color.black));
		
		timer = new Timer(16, new ActionListener() {
			@Override public void actionPerformed(ActionEvent arg0) {
				repaint();
			}
		});

		timer.start();
	}

    @Override
	public Dimension getPreferredSize() {
		return new Dimension(960, 640);
	}

	public void SetTrackModel(TrackModel trackModel)
	{
		this.trackModel = trackModel;
	}
	
    @Override
	public void paintComponent(Graphics graphics) {
		super.paintComponent(graphics);
		Graphics2D g = (Graphics2D)graphics;
		
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
		g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
		
		if (this.trackModel == null)
		{
			g.drawString("No TrackModel set!", 10, 100);
			return;
		}
		
		for (TrackSegment segment : this.trackModel.GetTrackSegments())
		{
			Vec2 mousePosition = new Vec2(-1, -1);
			
			if (this.getMousePosition(true) != null)
			{
				mousePosition = new Vec2(this.getMousePosition(true).x, this.getMousePosition(true).y);
			}
			
			if (segment.Poly.contains(mousePosition))
			{
				g.setColor(Color.RED);
			}
			else
			{
				g.setColor(Color.BLACK);
			}
			
			
            // draw Polygons
			Vec2[] vertices = segment.Poly.GetVertices();

			for (int i= 0; i < vertices.length; ++i)
			{
				Vec2 v0 = vertices[i];
				Vec2 v1 = vertices[(i + 1) % vertices.length];
				g.drawLine(v0.X, v0.Y, v1.X, v1.Y);
			}
			
			// Connect with arrows
			g.setColor(Color.BLACK);
			Vec2 center0 = segment.Poly.ComputeCenter();
			
			for (TrackSegment succ : segment.GetSuccessors())
			{
				Vec2 center1 = succ.Poly.ComputeCenter();
				
				g.drawLine(center0.X, center0.Y, center1.X, center1.Y);
				
                
				Vec2 diff = center1.substract(center0);
				Vec2 perp = diff.Perp1().Resized( 5 );
				
				Vec2 arrowHead1 = center1.substract(diff.Resized(10)).add(perp);
				Vec2 arrowHead2 = center1.substract(diff.Resized(10)).substract(perp);
				
				g.drawLine(arrowHead1.X, arrowHead1.Y, center1.X, center1.Y);
				g.drawLine(arrowHead2.X, arrowHead2.Y, center1.X, center1.Y);
			}
		}
        
        Side finishLine = this.trackModel.Last.Poly.adjacentSideWith(this.trackModel.First.Poly);
        g.setColor(Color.RED);
        
        g.drawLine(finishLine.PointA.X-1, finishLine.PointA.Y-1, finishLine.PointB.X-1, finishLine.PointB.Y-1);
        g.drawLine(finishLine.PointA.X+1, finishLine.PointA.Y-1, finishLine.PointB.X+1, finishLine.PointB.Y-1);
        g.drawLine(finishLine.PointA.X-1, finishLine.PointA.Y+1, finishLine.PointB.X-1, finishLine.PointB.Y+1);
        g.drawLine(finishLine.PointA.X+1, finishLine.PointA.Y+1, finishLine.PointB.X+1, finishLine.PointB.Y+1);
        g.drawLine(finishLine.PointA.X, finishLine.PointA.Y, finishLine.PointB.X, finishLine.PointB.Y);
	}
    
    
}
